package com.system.database;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.util.ClassUtils;

import com.github.pagehelper.PageHelper;

@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.portal")
public class MybatisConfig implements TransactionManagementConfigurer{
	/**
	 * Mybatis日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(MybatisConfig.class);

	/*@Autowired
	private DruidDataSourceConfig druidDataSourceConfig;*/
	@Autowired
	private DataSourceConfig dataSourceConfig;
	@Bean
	@Primary
	public DataSource dataSource() {
		DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默认数据源
        dynamicDataSource.setDefaultTargetDataSource(dataSourceConfig.businessDbDataSource());
        // 配置多数据源
        Map<Object, Object> dsMap = new HashMap<Object, Object>(3);
        dsMap.put("frameDb", dataSourceConfig.frameDbDataSource());
        dsMap.put("formDb", dataSourceConfig.formDbDataSource());
        dsMap.put("businessDb", dataSourceConfig.businessDbDataSource());
        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
	}


	@Bean
	@Primary
	public SqlSessionFactory sqlSessionFactory() throws Exception {
		logger.debug("--> sqlSessionFactory");
		final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
		sqlSessionFactory.setDataSource(dataSource());
		sqlSessionFactory.setFailFast(true);
		//sqlSessionFactory.setTypeAliasesPackage("com.igap.igp.model");
		//1.mybatis配置
		//sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
		Properties sqlSessionFactoryProperties = new Properties();
		sqlSessionFactoryProperties.setProperty("cacheEnabled", "true");
		sqlSessionFactoryProperties.setProperty("lazyLoadingEnabled", "true");
		sqlSessionFactoryProperties.setProperty("aggressiveLazyLoading", "true");
		sqlSessionFactoryProperties.setProperty("useGeneratedKeys", "false");
		sqlSessionFactoryProperties.setProperty("multipleResultSetsEnabled", "true");
		//sqlSessionFactoryProperties.setProperty("autoMappingBehavior", "PARTIAL");
		sqlSessionFactoryProperties.setProperty("mapUnderscoreToCamelCase", "true");
		//sqlSessionFactoryProperties.setProperty("useColumnLabel", "true");
		//SIMPLE REUSE BATCH
		sqlSessionFactoryProperties.setProperty("defaultExecutorType", "SIMPLE");
		sqlSessionFactoryProperties.setProperty("defaultStatementTimeout", "25");
		sqlSessionFactoryProperties.setProperty("jdbcTypeForNull", "NULL");
		sqlSessionFactoryProperties.setProperty("logImpl", "SLF4J");
		sqlSessionFactory.setConfigurationProperties(sqlSessionFactoryProperties);
		
		//分页插件
        PageHelper pageHelper = new PageHelper();
        Properties pageHelperProperties = new Properties();
        pageHelperProperties.setProperty("reasonable", "true");
        pageHelperProperties.setProperty("supportMethodsArguments", "true");
        pageHelperProperties.setProperty("returnPageInfo", "check");
        pageHelperProperties.setProperty("params", "count=countSql");
        pageHelperProperties.setProperty("offsetAsPageNum", "true");
        pageHelperProperties.setProperty("rowBoundsWithCount", "true");
        pageHelperProperties.setProperty("pageSizeZero", "true");
        pageHelperProperties.setProperty("autoRuntimeDialect", "true");
        pageHelper.setProperties(pageHelperProperties);
        
        //2.添加插件
        sqlSessionFactory.setPlugins(new Interceptor[]{pageHelper});
        
        //3.添加XML目录
		sqlSessionFactory.setMapperLocations(getResource("mapper", "**/*.xml"));
		return sqlSessionFactory.getObject();
	}
	/**
	 * SqlSessionTemplate
	 * @param sqlSessionFactory
	 * @return
	 * @throws Exception 
	 */
	@Bean
	@Primary
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory());
	}
	
//	@Bean
//    public DataSourceTransactionManager transactionManager() {
//        logger.debug("> transactionManager");
//        return new DataSourceTransactionManager(dataSource());
//    }
	

	@Bean
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return new DataSourceTransactionManager(dataSource());
	}


    @PostConstruct
    public void postConstruct() {
        //logger.info("jdbc.settings={}", druidDataSourceConfig);
    }

	public Resource[] getResource(String basePackage, String pattern) throws IOException {
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(new StandardEnvironment().resolveRequiredPlaceholders(basePackage)) + "/" + pattern;
		Resource[] resources = new PathMatchingResourcePatternResolver().getResources(packageSearchPath);
		return resources;
	}
}